#!/usr/bin/env python3
"""
机器学习训练数据集模块

本模块提供了用于机器学习模型训练的编程问题数据集，包含各种类型的编程问题
及其对应的标签和分类。数据集涵盖了计算机科学和编程竞赛中的常见问题类型。

主要功能：
- 提供结构化的训练数据集
- 支持多种编程问题类型的分类
- 提供数据集的统计和分析功能
- 支持数据集的保存和加载

数据集特点：
- 包含139个训练样本
- 涵盖10个主要类别：数学运算、数组操作、字符串处理、搜索算法、排序算法、
  数学问题、数据结构、图算法、动态规划、贪心算法
- 每个样本包含文本描述、标签和类别信息
- 支持中英文混合描述

技术特点：
- 使用JSON格式存储数据
- 支持UTF-8编码，兼容中文
- 提供数据集的统计分析功能
- 支持数据集的持久化存储

使用场景：
- 机器学习模型训练
- 自然语言处理研究
- 编程问题分类系统
- 智能教学辅助系统

依赖关系：
- json：JSON数据处理
- typing：类型注解支持
"""

import json
from typing import List, Dict, Any

class ProblemDataset:
    """
    编程问题数据集类
    
    提供结构化的机器学习训练数据集，包含各种编程问题的文本描述、
    标签和分类信息。数据集涵盖了计算机科学和编程竞赛中的常见问题类型。
    
    主要功能：
    1. 数据管理：提供训练数据的创建、获取和管理
    2. 统计分析：提供数据集的统计信息和分布分析
    3. 数据持久化：支持数据集的保存和加载
    4. 数据访问：提供多种数据访问接口
    
    数据集结构：
    每个训练样本包含以下字段：
    - text: 问题描述文本（中文）
    - label: 具体的问题类型标签（英文）
    - category: 问题的大类别（英文）
    
    类别说明：
    - math: 数学运算类（加法、减法、乘法、除法等）
    - array: 数组操作类（求和、最大值、最小值、排序等）
    - string: 字符串操作类（反转、长度、回文、计数等）
    - search: 搜索算法类（线性搜索、二分搜索等）
    - sort: 排序算法类（冒泡排序、快速排序、归并排序等）
    - data_structure: 数据结构类（栈、队列、链表等）
    - graph: 图算法类（DFS、BFS、最短路径等）
    - dp: 动态规划类（背包问题、LCS、LIS等）
    - greedy: 贪心算法类（活动选择、硬币找零等）
    
    使用示例：
        # 创建数据集
        dataset = ProblemDataset()
        
        # 获取训练数据
        training_data = dataset.get_training_data()
        
        # 获取文本和标签
        texts, labels = dataset.get_texts_and_labels()
        
        # 获取统计信息
        categories = dataset.get_categories()
        labels = dataset.get_labels()
        
        # 保存数据集
        dataset.save_dataset("my_dataset.json")
    """
    
    def __init__(self):
        """
        初始化数据集
        
        创建ProblemDataset实例，自动加载预定义的训练数据。
        训练数据包含139个样本，涵盖10个主要类别。
        """
        # 创建训练数据集
        self.training_data = self._create_training_data()
    
    def _create_training_data(self) -> List[Dict[str, Any]]:
        """
        创建训练数据集
        
        构建包含各种编程问题类型的训练数据集。数据集按类别组织，
        每个类别包含多个相似但表达方式不同的问题描述，以提高模型的泛化能力。
        
        返回:
            List[Dict[str, Any]]: 训练数据列表，每个元素包含text、label、category字段
            
        数据组织：
        1. 数学运算类 (math): 基本四则运算
        2. 数组操作类 (array): 数组的常见操作
        3. 字符串操作类 (string): 字符串处理
        4. 搜索算法类 (search): 各种搜索算法
        5. 排序算法类 (sort): 各种排序算法
        6. 数学问题类 (math): 高级数学问题
        7. 数据结构类 (data_structure): 基本数据结构
        8. 图算法类 (graph): 图论算法
        9. 动态规划类 (dp): 动态规划问题
        10. 贪心算法类 (greedy): 贪心算法问题
        """
        return [
            # 数学运算类 - 基本四则运算问题
            # 包含加法、减法、乘法、除法等基本运算的描述
            {"text": "计算两个整数的和", "label": "addition", "category": "math"},
            {"text": "给定两个数a和b，求a+b的结果", "label": "addition", "category": "math"},
            {"text": "输入两个整数，输出它们的和", "label": "addition", "category": "math"},
            {"text": "计算两个数的乘积", "label": "multiplication", "category": "math"},
            {"text": "给定两个数，求它们的乘积", "label": "multiplication", "category": "math"},
            {"text": "输入两个整数，输出它们的乘积", "label": "multiplication", "category": "math"},
            {"text": "计算两个数的差", "label": "subtraction", "category": "math"},
            {"text": "给定两个数a和b，求a-b的结果", "label": "subtraction", "category": "math"},
            {"text": "计算两个数的商", "label": "division", "category": "math"},
            {"text": "给定两个数a和b，求a/b的结果", "label": "division", "category": "math"},
            
            # 数组操作类 - 数组的常见操作问题
            # 包含求和、最大值、最小值、排序等数组操作
            {"text": "计算数组中所有元素的和", "label": "array_sum", "category": "array"},
            {"text": "给定一个整数数组，求所有元素的和", "label": "array_sum", "category": "array"},
            {"text": "输入一个数组，输出所有元素的和", "label": "array_sum", "category": "array"},
            {"text": "找到数组中的最大值", "label": "array_max", "category": "array"},
            {"text": "给定一个数组，找出最大的元素", "label": "array_max", "category": "array"},
            {"text": "输入一个数组，输出最大值", "label": "array_max", "category": "array"},
            {"text": "找到数组中的最小值", "label": "array_min", "category": "array"},
            {"text": "给定一个数组，找出最小的元素", "label": "array_min", "category": "array"},
            {"text": "输入一个数组，输出最小值", "label": "array_min", "category": "array"},
            {"text": "对数组进行排序", "label": "array_sort", "category": "array"},
            {"text": "给定一个数组，将其按升序排列", "label": "array_sort", "category": "array"},
            {"text": "输入一个数组，输出排序后的数组", "label": "array_sort", "category": "array"},
            
            # 字符串操作类 - 字符串处理问题
            # 包含反转、长度计算、回文判断、字符计数等字符串操作
            {"text": "反转字符串", "label": "string_reverse", "category": "string"},
            {"text": "给定一个字符串，将其反转", "label": "string_reverse", "category": "string"},
            {"text": "输入一个字符串，输出反转后的字符串", "label": "string_reverse", "category": "string"},
            {"text": "计算字符串的长度", "label": "string_length", "category": "string"},
            {"text": "给定一个字符串，求其长度", "label": "string_length", "category": "string"},
            {"text": "输入一个字符串，输出其长度", "label": "string_length", "category": "string"},
            {"text": "判断字符串是否为回文", "label": "string_palindrome", "category": "string"},
            {"text": "给定一个字符串，判断是否为回文", "label": "string_palindrome", "category": "string"},
            {"text": "输入一个字符串，判断是否为回文", "label": "string_palindrome", "category": "string"},
            {"text": "统计字符串中某个字符的出现次数", "label": "string_count", "category": "string"},
            {"text": "给定一个字符串和一个字符，统计该字符的出现次数", "label": "string_count", "category": "string"},
            
            # 搜索算法类 - 各种搜索算法问题
            # 包含线性搜索、二分搜索等经典搜索算法
            {"text": "在数组中查找指定元素", "label": "linear_search", "category": "search"},
            {"text": "给定一个数组和一个目标值，查找目标值的位置", "label": "linear_search", "category": "search"},
            {"text": "输入一个数组和目标值，输出目标值的位置", "label": "linear_search", "category": "search"},
            {"text": "使用二分查找在有序数组中查找元素", "label": "binary_search", "category": "search"},
            {"text": "给定一个有序数组和目标值，使用二分查找", "label": "binary_search", "category": "search"},
            {"text": "输入一个有序数组和目标值，使用二分查找", "label": "binary_search", "category": "search"},
            
            # 排序算法类 - 各种排序算法问题
            # 包含冒泡排序、快速排序、归并排序等经典排序算法
            {"text": "使用冒泡排序对数组进行排序", "label": "bubble_sort", "category": "sort"},
            {"text": "给定一个数组，使用冒泡排序算法", "label": "bubble_sort", "category": "sort"},
            {"text": "输入一个数组，使用冒泡排序", "label": "bubble_sort", "category": "sort"},
            {"text": "使用快速排序对数组进行排序", "label": "quick_sort", "category": "sort"},
            {"text": "给定一个数组，使用快速排序算法", "label": "quick_sort", "category": "sort"},
            {"text": "输入一个数组，使用快速排序", "label": "quick_sort", "category": "sort"},
            {"text": "使用归并排序对数组进行排序", "label": "merge_sort", "category": "sort"},
            {"text": "给定一个数组，使用归并排序算法", "label": "merge_sort", "category": "sort"},
            {"text": "输入一个数组，使用归并排序", "label": "merge_sort", "category": "sort"},
            
            # 数学问题类 - 高级数学问题
            # 包含阶乘、质数判断、斐波那契数列、最大公约数等数学问题
            {"text": "计算阶乘", "label": "factorial", "category": "math"},
            {"text": "给定一个整数n，计算n的阶乘", "label": "factorial", "category": "math"},
            {"text": "输入一个整数，输出其阶乘", "label": "factorial", "category": "math"},
            {"text": "判断一个数是否为质数", "label": "prime_check", "category": "math"},
            {"text": "给定一个整数，判断是否为质数", "label": "prime_check", "category": "math"},
            {"text": "输入一个整数，判断是否为质数", "label": "prime_check", "category": "math"},
            {"text": "计算斐波那契数列的第n项", "label": "fibonacci", "category": "math"},
            {"text": "给定一个整数n，计算斐波那契数列的第n项", "label": "fibonacci", "category": "math"},
            {"text": "输入一个整数n，输出斐波那契数列的第n项", "label": "fibonacci", "category": "math"},
            {"text": "计算最大公约数", "label": "gcd", "category": "math"},
            {"text": "给定两个整数，计算它们的最大公约数", "label": "gcd", "category": "math"},
            {"text": "输入两个整数，输出它们的最大公约数", "label": "gcd", "category": "math"},
            
            # 数据结构类 - 基本数据结构问题
            # 包含栈、队列、链表等基本数据结构的实现和操作
            {"text": "实现栈的基本操作", "label": "stack", "category": "data_structure"},
            {"text": "给定一个栈，实现push和pop操作", "label": "stack", "category": "data_structure"},
            {"text": "输入栈操作序列，输出栈的状态", "label": "stack", "category": "data_structure"},
            {"text": "实现队列的基本操作", "label": "queue", "category": "data_structure"},
            {"text": "给定一个队列，实现enqueue和dequeue操作", "label": "queue", "category": "data_structure"},
            {"text": "输入队列操作序列，输出队列的状态", "label": "queue", "category": "data_structure"},
            {"text": "实现链表的基本操作", "label": "linked_list", "category": "data_structure"},
            {"text": "给定一个链表，实现插入和删除操作", "label": "linked_list", "category": "data_structure"},
            {"text": "输入链表操作序列，输出链表的状态", "label": "linked_list", "category": "data_structure"},
            
            # 图算法类 - 图论算法问题
            # 包含深度优先搜索、广度优先搜索、最短路径等图算法
            {"text": "实现深度优先搜索", "label": "dfs", "category": "graph"},
            {"text": "给定一个图，实现深度优先搜索", "label": "dfs", "category": "graph"},
            {"text": "输入一个图，使用深度优先搜索遍历", "label": "dfs", "category": "graph"},
            {"text": "实现广度优先搜索", "label": "bfs", "category": "graph"},
            {"text": "给定一个图，实现广度优先搜索", "label": "bfs", "category": "graph"},
            {"text": "输入一个图，使用广度优先搜索遍历", "label": "bfs", "category": "graph"},
            {"text": "实现最短路径算法", "label": "shortest_path", "category": "graph"},
            {"text": "给定一个图，计算两个节点之间的最短路径", "label": "shortest_path", "category": "graph"},
            {"text": "输入一个图和两个节点，输出最短路径", "label": "shortest_path", "category": "graph"},
            
            # 动态规划类 - 动态规划问题
            # 包含背包问题、最长公共子序列、最长递增子序列等经典DP问题
            {"text": "解决背包问题", "label": "knapsack", "category": "dp"},
            {"text": "给定物品重量和价值，解决0-1背包问题", "label": "knapsack", "category": "dp"},
            {"text": "输入物品信息，输出最大价值", "label": "knapsack", "category": "dp"},
            {"text": "计算最长公共子序列", "label": "lcs", "category": "dp"},
            {"text": "给定两个字符串，计算最长公共子序列", "label": "lcs", "category": "dp"},
            {"text": "输入两个字符串，输出最长公共子序列", "label": "lcs", "category": "dp"},
            {"text": "计算最长递增子序列", "label": "lis", "category": "dp"},
            {"text": "给定一个数组，计算最长递增子序列", "label": "lis", "category": "dp"},
            {"text": "输入一个数组，输出最长递增子序列", "label": "lis", "category": "dp"},
            
            # 贪心算法类 - 贪心算法问题
            # 包含活动选择问题、硬币找零问题等经典贪心算法问题
            {"text": "解决活动选择问题", "label": "activity_selection", "category": "greedy"},
            {"text": "给定一系列活动，选择最多不冲突的活动", "label": "activity_selection", "category": "greedy"},
            {"text": "输入活动时间，输出最优活动选择", "label": "activity_selection", "category": "greedy"},
            {"text": "解决硬币找零问题", "label": "coin_change", "category": "greedy"},
            {"text": "给定硬币面额和目标金额，找最少的硬币数", "label": "coin_change", "category": "greedy"},
            {"text": "输入硬币面额和目标金额，输出最少硬币数", "label": "coin_change", "category": "greedy"},
            
            # 更多变体 - 特殊数学问题
            # 包含煤球问题、三角形数等特殊数学问题
            {"text": "计算煤球的总数", "label": "sum_series", "category": "math"},
            {"text": "给定层数n，计算n层煤球的总数", "label": "sum_series", "category": "math"},
            {"text": "输入层数，输出煤球总数", "label": "sum_series", "category": "math"},
            {"text": "计算三角形数", "label": "triangular_number", "category": "math"},
            {"text": "给定一个数n，计算第n个三角形数", "label": "triangular_number", "category": "math"},
            {"text": "输入一个数n，输出第n个三角形数", "label": "triangular_number", "category": "math"},
        ]
    
    def get_training_data(self) -> List[Dict[str, Any]]:
        """
        获取完整的训练数据集
        
        返回包含所有训练样本的列表，每个样本包含text、label、category字段。
        
        返回:
            List[Dict[str, Any]]: 训练数据列表
                每个元素包含：
                - text (str): 问题描述文本
                - label (str): 问题类型标签
                - category (str): 问题类别
                
        使用示例:
            dataset = ProblemDataset()
            training_data = dataset.get_training_data()
            print(f"训练样本数量: {len(training_data)}")
        """
        return self.training_data
    
    def get_texts_and_labels(self) -> tuple:
        """
        获取文本和标签的分离数据
        
        将训练数据分离为文本列表和标签列表，便于机器学习模型训练使用。
        
        返回:
            tuple: (texts, labels) 元组
                - texts (List[str]): 问题描述文本列表
                - labels (List[str]): 对应的标签列表
                
        使用示例:
            dataset = ProblemDataset()
            texts, labels = dataset.get_texts_and_labels()
            print(f"文本数量: {len(texts)}")
            print(f"标签数量: {len(labels)}")
            print(f"第一个文本: {texts[0]}")
            print(f"第一个标签: {labels[0]}")
        """
        texts = [item["text"] for item in self.training_data]
        labels = [item["label"] for item in self.training_data]
        return texts, labels
    
    def get_categories(self) -> List[str]:
        """
        获取所有问题类别
        
        从训练数据中提取所有唯一的问题类别，用于了解数据集的分类情况。
        
        返回:
            List[str]: 唯一类别列表，包含所有问题的大类别
            
        类别说明:
            - math: 数学运算和数学问题
            - array: 数组操作
            - string: 字符串处理
            - search: 搜索算法
            - sort: 排序算法
            - data_structure: 数据结构
            - graph: 图算法
            - dp: 动态规划
            - greedy: 贪心算法
            
        使用示例:
            dataset = ProblemDataset()
            categories = dataset.get_categories()
            print(f"数据集包含{len(categories)}个类别: {categories}")
        """
        return list(set(item["category"] for item in self.training_data))
    
    def get_labels(self) -> List[str]:
        """
        获取所有问题标签
        
        从训练数据中提取所有唯一的问题标签，用于了解数据集的具体问题类型。
        
        返回:
            List[str]: 唯一标签列表，包含所有具体的问题类型标签
            
        标签说明:
            数据集包含约30个不同的标签，涵盖：
            - 数学运算: addition, subtraction, multiplication, division
            - 数组操作: array_sum, array_max, array_min, array_sort
            - 字符串处理: string_reverse, string_length, string_palindrome, string_count
            - 搜索算法: linear_search, binary_search
            - 排序算法: bubble_sort, quick_sort, merge_sort
            - 数学问题: factorial, prime_check, fibonacci, gcd
            - 数据结构: stack, queue, linked_list
            - 图算法: dfs, bfs, shortest_path
            - 动态规划: knapsack, lcs, lis
            - 贪心算法: activity_selection, coin_change
            - 特殊数学: sum_series, triangular_number
            
        使用示例:
            dataset = ProblemDataset()
            labels = dataset.get_labels()
            print(f"数据集包含{len(labels)}个标签")
            for label in sorted(labels):
                print(f"  - {label}")
        """
        return list(set(item["label"] for item in self.training_data))
    
    def save_dataset(self, filepath: str):
        """
        保存数据集到JSON文件
        
        将训练数据集保存为JSON格式文件，支持UTF-8编码，便于数据持久化和分享。
        
        参数:
            filepath (str): 保存文件的路径
            
        异常:
            IOError: 文件写入失败时抛出
            json.JSONEncodeError: JSON编码失败时抛出
            
        使用示例:
            dataset = ProblemDataset()
            dataset.save_dataset("my_dataset.json")
            print("数据集已保存")
        """
        with open(filepath, 'w', encoding='utf-8') as f:
            json.dump(self.training_data, f, ensure_ascii=False, indent=2)
    
    def load_dataset(self, filepath: str):
        """
        从JSON文件加载数据集
        
        从指定的JSON文件中加载训练数据集，替换当前的数据集内容。
        支持UTF-8编码，确保中文字符正确显示。
        
        参数:
            filepath (str): 数据集文件的路径
            
        异常:
            IOError: 文件读取失败时抛出
            json.JSONDecodeError: JSON解析失败时抛出
            
        使用示例:
            dataset = ProblemDataset()
            dataset.load_dataset("my_dataset.json")
            print(f"已加载{len(dataset.training_data)}个训练样本")
        """
        with open(filepath, 'r', encoding='utf-8') as f:
            self.training_data = json.load(f)

if __name__ == "__main__":
    """
    主程序入口
    
    当直接运行此文件时，会执行以下操作：
    1. 创建数据集实例
    2. 显示数据集的统计信息
    3. 分析类别和标签的分布
    4. 保存数据集到JSON文件
    
    这个演示程序展示了数据集的基本功能和使用方法。
    """
    
    # 创建数据集实例
    dataset = ProblemDataset()
    
    # 显示数据集的基本统计信息
    print(f"数据集统计:")
    print(f"  总样本数: {len(dataset.training_data)}")
    print(f"  类别数: {len(dataset.get_categories())}")
    print(f"  标签数: {len(dataset.get_labels())}")
    
    # 分析类别分布
    print(f"\n类别分布:")
    categories = dataset.get_categories()
    for category in categories:
        # 统计每个类别的样本数量
        count = sum(1 for item in dataset.training_data if item["category"] == category)
        print(f"  {category}: {count} 个样本")
    
    # 分析标签分布
    print(f"\n标签分布:")
    labels = dataset.get_labels()
    for label in labels:
        # 统计每个标签的样本数量
        count = sum(1 for item in dataset.training_data if item["label"] == label)
        print(f"  {label}: {count} 个样本")
    
    # 保存数据集到JSON文件
    dataset.save_dataset("problem_dataset.json")
    print(f"\n数据集已保存到 problem_dataset.json")
